//
//  AppCommand.swift
//  PokeMaster
//
//  Created by 李腾芳 on 2022/1/11.
//  Copyright © 2022 OneV's Den. All rights reserved.
//

import Foundation
import Combine

protocol AppCommand {
    func execute(in store: Store) -> AnyCancellable
}

struct LogonAppCommand: AppCommand {
    let email: String
    let password: String
    func execute(in store: Store) -> AnyCancellable {
        LogonRequest(email: email, password: password)
            .publisher
            .print()
            .share()
            .sink(receiveCompletion: { complete in
                if case .failure(let error) = complete {
                    store.dispatch(
                        AppAction.settings(.accountBehaviorDone(result: .failure(error)))
                    )
                }
            }, receiveValue: { user in
                store.dispatch(
                    AppAction.settings(.accountBehaviorDone(result: .success(user)))
                )
            })
            
    }
    
//    deinit {
//        print("deinit")
//    }
    
    init(email: String, password: String) {
        self.email = email
        self.password = password
    }
}

struct WriteUserCommand: AppCommand {
    func execute(in store: Store) -> AnyCancellable {
        try? FileHelper.writeJSON(store.appState.settings.user, to: .documentDirectory, fileName: "user.json")
        return Empty<User, AppError>().sink { complete in
            
        } receiveValue: { _ in
            
        }

    }
}

struct LoadPokeMenCommand: AppCommand {
    func execute(in store: Store) -> AnyCancellable {
        LoadPokeManRequest.all().sink { complete in
            if case .failure(let error) = complete {
                store.dispatch(AppAction.home(.loadPokeMenListDone(result: .failure(error))))
            }
        } receiveValue: { models in
            store.dispatch(AppAction.home(.loadPokeMenListDone(result: .success(models))))
        }

    }
}

struct RegisterCommand: AppCommand {
    let email: String
    let password: String
    
    func execute(in store: Store) -> AnyCancellable {
        RegisterRequest(email: email, password: password)
            .publisher
            .sink { complete in
                if case .failure(let error) = complete {
                    store.dispatch(AppAction.settings(.accountRegisterDone(result: .failure(error))))
                }
            } receiveValue: { result in
                store.dispatch(AppAction.settings(.accountRegisterDone(result: .success(result))))
            }
        
    }
}
